<?php

namespace Biz\service\brand;

use Biz\model\brand\Brand as mBrand;
use Biz\model\brandActivity\BlindBoxActivity as mBlindBoxActivity;
use Biz\model\brandActivity\BlindBoxActivityPrize as mBlindBoxActivityPrize;
use Biz\model\brandActivity\BlindBoxLottery as mBlindBoxLottery;
use Biz\model\brandActivity\BrandActivityBasic;
use Biz\model\brandRights\BrandRightsRecored;
use Biz\pockets\constInterface\BlindBoxConfig;
use Biz\pockets\constInterface\SourceRightsInterface;
use Biz\service\BrandRights\BrandEquityVerificationService;
use Doraemon\service\User as sUser;
use Doraemon\tools\Log;

class BlindBoxActivity implements BlindBoxConfig
{

    /**
     * 保存盲盒活动信息
     * @param array $activityData
     * @param $prizeValue
     * @param string $rightsName
     * @return array|bool
     * @throws \Exception
     */
    public static function saveBlindBoxActivity(array $activityData, $prizeValue, string $rightsName = '')
    {
        $isConsumerRights = false;
        $activityData['activity_type'] = mBlindBoxActivity::ACTIVITY_TYPE_BLIND_BOX;
        $id = $activityData['id'] ?? 0;
        $activityId = $id;
        $result = true;
        if ($id) {
            $info = mBlindBoxActivity::getInfoById($id);
            if (empty($info)) {
                throw new \Exception('不存在的活动');
            }
            //编辑草稿并保存为待审核，消耗活动次数
            if ($result && $activityData['brand_id'] > 0
                && in_array($info['activity_state'],
                    [mBlindBoxActivity::ACTIVITY_STATE_DRAFT, mBlindBoxActivity::ACTIVITY_STATE_UN_PASS])
                && $activityData['activity_state'] == mBlindBoxActivity::ACTIVITY_STATE_NORMAL) {
                //编辑的时候。如果之前状态为待审核或则审核未通过，并且当前状态为待审核，则消耗活动次数
                $isConsumerRights = true;
            }
        } else {
            if ($activityData['brand_id'] > 0 && $activityData['activity_state'] == mBlindBoxActivity::ACTIVITY_STATE_NORMAL) {//新添加活动不是草稿状态，消耗一次活动次数
                $isConsumerRights = true;
            }
        }

        if ($id) {//edit
            $info = mBlindBoxActivity::getByWhere(['id' => $id, 'brand_id' => $activityData['brand_id']]);
            if (!$info) {
                throw new \Exception('不存在的活动');
            }
            $now = time();
            if ($info['activity_state'] == mBlindBoxActivity::ACTIVITY_STATE_PASS && $now >= $info['start_time']) {
                throw new \Exception('当前状态不支持编辑');
            }
            if ($info['activity_type'] != $activityData['activity_type']) {
                throw new \Exception('活动类型错误');
            }
            if ($info['prize_type'] != $activityData['prize_type']) {
                throw new \Exception('奖品类型不能编辑');
            }
            $activityPrizeList = mBlindBoxActivityPrize::getActivityPrizeList($id);
            if ($activityPrizeList) {
                unset($activityData['id']);
                $activityPrizeList = $activityPrizeList[$id];
                $result = mBlindBoxActivity::action(function () use (
                    $info,
                    $activityData,
                    $prizeValue,
                    $activityPrizeList
                ) {
                    $allPrizeValues = array_column($activityPrizeList, 'prize_value');
                    $delPrizeValue = array_diff($allPrizeValues, $prizeValue);
                    $addPrizeValue = array_diff($prizeValue, $allPrizeValues);
                    foreach ($activityPrizeList as $row) {
                        if ($row['prize_state'] == mBlindBoxActivityPrize::PRIZE_STATE_RECEIVED) {//如果有奖品被领取了
                            if (in_array($row['prize_value'], $delPrizeValue)) {
                                throw new \Exception('奖品：『' . $row['prize_value'] . '』已经被用户领取,不能删除');
                            }
                        }
                    }
                    $result = mBlindBoxActivity::updateData($activityData, ['id' => $info['id']]);
                    if ($result) {
                        if ($delPrizeValue) {
                            $delWhere = [
                                'prize_value' => $delPrizeValue,
                                'activity_id' => $info['id'],
                                'prize_state' => mBlindBoxActivityPrize::PRIZE_STATE_NORMAL
                            ];
                            $result = mBlindBoxActivityPrize::updateData(['prize_state' => mBlindBoxActivityPrize::PRIZE_STATE_DEL],
                                $delWhere);
                            if (!$result) {
                                Log::debug('编辑奖品失败,删除已有奖品失败#sql:' . json_encode(mBlindBoxActivityPrize::log(),
                                        JSON_UNESCAPED_UNICODE));
                                throw  new \Exception('编辑奖品失败');
                            }
                        }
                        foreach ($addPrizeValue as $value) {
                            $addPrizeData = [
                                'activity_id' => $info['id'],
                                'prize_type' => $info['prize_type'],
                                'prize_value' => $value,
                                'prize_state' => mBlindBoxActivityPrize::PRIZE_STATE_NORMAL,
                            ];
                            $result = mBlindBoxActivityPrize::insertData($addPrizeData);
                            if (!$result) {
                                Log::debug('添加奖品失败#sql:' . json_encode(mBlindBoxActivityPrize::log(),
                                        JSON_UNESCAPED_UNICODE));
                                throw new \Exception('添加奖品失败');
                            }
                        }
                    } else {
                        Log::debug('编辑活动失败#sql:' . json_encode(mBlindBoxActivityPrize::log(), JSON_UNESCAPED_UNICODE));
                        throw new \Exception('编辑活动失败');
                    }
                    return true;
                });
            }
        } else {//insert
            $result = mBlindBoxActivity::action(function () use ($activityData, $prizeValue) {
                $activityId = mBlindBoxActivity::insertData($activityData);
                if ($activityId) {
                    foreach ($prizeValue as $value) {
                        $addPrizeData = [
                            'activity_id' => $activityId,
                            'prize_type' => $activityData['prize_type'],
                            'prize_value' => $value,
                            'prize_state' => mBlindBoxActivityPrize::PRIZE_STATE_NORMAL,
                        ];
                        $result = mBlindBoxActivityPrize::insertData($addPrizeData);
                        if (!$result) {
                            Log::debug('添加奖品失败#sql:' . json_encode(mBlindBoxActivityPrize::log(),
                                    JSON_UNESCAPED_UNICODE));
                            throw new \Exception('添加奖品失败');
                        }
                    }
                } else {
                    Log::debug('添加活动失败#sql:' . json_encode(mBlindBoxActivityPrize::log(), JSON_UNESCAPED_UNICODE));
                    throw new \Exception('添加活动失败');
                }
                return $activityId;
            });
            $activityId = $result;
        }
        //权益数量操作
        $sourceId = BrandActivityBasic::getSourceId(BrandActivityBasic::ACTIVITY_TYPE_BLIND_BOX, $activityId);

        //操作盲盒数量
        if ($isConsumerRights) {
            $dataParams = [
                $activityData['brand_id'],
                SourceRightsInterface::BLIND_BOX,
                BrandRightsRecored::RECORED_TYPE_CONSUME,
                BrandRightsRecored::OPERATE_USER_TYPE_SYS,
                $sourceId,
            ];

            $res = BrandEquityVerificationService::addOrSubBrandSourceNum(...$dataParams);

            if (!$res) {
                throw new \Exception('系统错误！请重试');
            }
        }
        return $result;
    }

    /**
     * 查询wiki当前参与的活动
     * @param $basicIds
     * @return array
     */
    public static function getWikiActivityList($basicIds)
    {
        $result = [];
        $now = time();
        $where = [
            'activity_type' => mBlindBoxActivity::ACTIVITY_TYPE_BLIND_BOX,
            'prize_type' => [mBlindBoxActivity::PRIZE_TYPE_GOODS, mBlindBoxActivity::PRIZE_TYPE_GOOD_COUPON],
            'basic_id' => $basicIds,
            'start_time[<=]' => $now,
            'end_time[>=]' => $now,
            'activity_state' => mBlindBoxActivity::ACTIVITY_STATE_PASS,
            'ORDER' => ['end_time' => 'ASC']
        ];
        $activityList = mBlindBoxActivity::selectByWhere($where,
            ['id', 'brand_id', 'prize_type', 'basic_id', 'prize_title', 'prize_price', 'prize_img']);
        foreach ($activityList as $row) {
            if (!isset($result[$row['basic_id']])) {
                $result[$row['basic_id']] = $row;
            }
        }
        return $result;
    }

    public static function shippingRemind($activityId = null)
    {
        if (empty($activityId)) {
            //检查昨天结束的活动，提醒品牌发货
            $startTime = strtotime(date('Y-m-d', strtotime('-1 days')));
            $endTime = $startTime + 86399;
            $where = [
                'activity_state' => mBlindBoxActivity::ACTIVITY_STATE_PASS,
                'end_time[>=]' => $startTime,
                'end_time[<=]' => $endTime,
                'brand_id[>]' => 0,
                'prize_type' => mBlindBoxActivity::PRIZE_TYPE_GOODS
            ];
        } else {
            $where = [
                'id' => $activityId,
                'activity_state' => mBlindBoxActivity::ACTIVITY_STATE_PASS,
                'brand_id[>]' => 0,
                'prize_type' => mBlindBoxActivity::PRIZE_TYPE_GOODS
            ];
        }
        $brandIds = mBlindBoxActivity::selectByWhere($where, 'brand_id');
        $brandList = $brandIds ? mBrand::selectByWhere(['id' => $brandIds], ['uid']) : [];
        $uids = $brandList ? array_column($brandList, 'uid') : [];

        foreach ($uids as $uid) {
            self::sendMsg($uid, '盲盒奖品发货提醒', '已收到中奖用户的收货地址，请尽快发货，并记得登录品牌服务平台填写物流单号哦～');
        }
    }

    /**
     * 提醒用户中奖的奖品已发货
     * @param $lotteryId 中奖id
     * @param $expressNo 物流单号
     */
    public static function lotteryRemind($lotteryId, $expressNo)
    {
        $lotteryInfo = mBlindBoxLottery::getByWhere(['id' => $lotteryId]);
        if (!empty($lotteryInfo)) {
            $detail = sprintf('盲盒奖品「%s」已寄出，物流单号：%s，请注意查收。', $lotteryInfo['prize_title'], $expressNo);
            self::sendMsg($lotteryInfo['uid'], '盲盒奖品已寄出', $detail);
        }
    }

    /**
     * 发送系统消息
     * @param $uid
     * @param $title
     * @param $detail
     */
    public static function sendMsg($uid, $title, $detail)
    {
        if (!empty($uid)) {
            $data = [
                'msgCode' => 0,
                'to_uid' => $uid,
                'msgParams' => [
                    'from_uid' => sUser::DEFAULT_HAOHAOZHU_UID,
                    'title' => $title,
                    'detail' => $detail,
                    'type' => 1,
                ]
            ];
            \Doraemon\cache\Queue::insertQueue('queue/Sysmsg/Send', $data, \Doraemon\cache\Queue::QUEUE_DORAEMON);
        }
    }

}